#pragma once

#ifndef VTTCONFIGURATION_H
#define VTTCONFIGURATION_H

#include "VTTObject.h"
#include "VTTDataTypes.h"

#include <string>
#include <vector>

/**
  *	Struct that capsules all the parameters of a VTTConfiguration object
  */
struct VTTConfigurationOptions
{
	VTTConfigurationOptions(
		const std::string &atlasName, const std::string &basePath, const std::string &tileStoreName,
		UINT32 border, UINT32 maxAtlasPartSize, UINT32 pictureQuality, UINT32 tileSize,
		UINT32 kernelSize, float kernelSigma, UINT32 imageBlockWidth, UINT32 imageBlockHeight,
		const std::vector<std::string> &imageBlockImageNames,
		VTTImageFormat tilesFormat, VTTImageFormat atlasFormat ) :
			mAtlasName( atlasName ),
			mBasePath( basePath ),
			mTileStoreName( tileStoreName ),
			mBorder( border ),
			mMaxAtlasPartSize( maxAtlasPartSize ),
			mPictureQuality( pictureQuality ),
			mTileSize( tileSize ),
			mKernelSize( kernelSize ),
			mKernelSigma( kernelSigma ),
			mImageBlockWidth( imageBlockWidth ),
			mImageBlockHeight( imageBlockHeight ),
			mImageBlockImageNames( imageBlockImageNames ),
			mTilesFormat( tilesFormat ),
			mAtlasFormat( atlasFormat ) {};

	/** The name (not the path!) of the directory containing the Virtual Texture Atlas */
	std::string mAtlasName;
	/** Path of the base directory, containing all images for the Atlas as well as the directories for the Atlas and the Tile Store */
	std::string mBasePath;
	/** The name (not the path!) of the directory containing the Tile Store */
	std::string mTileStoreName;

	/** Width of the overlapping region between consecutive tiles, value in [0..4] */
	UINT32 mBorder;
	/** Maximum of the side length for a single part of the Virtual Texture Atlas */
	UINT32 mMaxAtlasPartSize;
	/** Quality parameter for the Jpeg compression algorithm (the higher, the better), value in [0..100] */
	UINT32 mPictureQuality;
	/** Side length of a single tile, possible values are 64, 128, 256 and 512 */
	UINT32 mTileSize;

	/** Side length of the gaussian filter kernel that is used for scaling of the images */
	UINT32 mKernelSize;
	/** Root mean square deviation of the gaussian function used for scaling of the images */
	float mKernelSigma;

	/** Number of images in the horizontal direction in the optional imageBlock */
	UINT32 mImageBlockWidth;
	/** Number of images in the vertical direction in the optional imageBlock */
	UINT32 mImageBlockHeight;
	/** Names of all the images in the optional imageBlock. The names have to be ordered from left to right, top to bottom */
	std::vector<std::string> mImageBlockImageNames;

	/** Enum value corresponding to the file format, that is used to store the tiles in the Tile Store */
	VTTImageFormat mTilesFormat;
	/** Enum value corresponding to the file format, that is used to store the Atlas parts */
	VTTImageFormat mAtlasFormat;
};

/**
  * Configuration for the Virtual Texture Atlas and Tile Store generation process.
  */
class VTTConfiguration : public VTTObject
{

public:

	VTTConfiguration( void );
	VTTConfiguration( const VTTConfigurationOptions &configOptions );
	VTTConfiguration( const std::string *basePath );
	VTTConfiguration( const std::string &fileName );

	bool LoadFromFile( const std::string &fileName );

	const std::string &GetAtlasName( void ) const;
	const std::string &GetBasePath( void ) const;
	const std::string &GetTileStoreName( void ) const;

	UINT32 GetBorder( void ) const;
	UINT32 GetImageBlockHeight( void ) const;
	UINT32 GetImageBlockWidth( void ) const;
	const std::vector<std::string> &GetImageBlockImageNames( void ) const;
	
	float GetKernelSigma( void ) const;
	UINT32 GetKernelSize( void ) const;
	UINT32 GetMaxAtlasPartSize( void ) const;
	UINT32 GetPictureQuality( void ) const;
	UINT32 GetTileSize( void ) const;

	VTTImageFormat GetAtlasFormat( void ) const;
	VTTImageFormat GetTilesFormat( void ) const;

	void SetDefaultValues( const std::string &basePath );
	bool SetParameters( const VTTConfigurationOptions &configOptions );

	std::string WriteToDisc( void );

	static bool IsNonEmptyImageDirectory( const std::string &imageDirectoryPath );
	static bool IsValidBorderSize( UINT32 border );
	static bool IsValidTileSize( UINT32 tileSize );
	
private:

	/** The name (not the path!) of the directory containing the Virtual Texture Atlas */
	std::string mAtlasName;
	/** Path of the base directory, containing all images for the Atlas as well as the directories for the Atlas and the Tile Store */
	std::string mBasePath;
	/** Name of the Configuration file on hard disc */
	std::string mFileName;
	/** The name (not the path!) of the directory containing the Tile Store */
	std::string mTileStoreName;

	/** Width of the overlapping region between consecutive tiles, value in [0..4] */
	UINT32 mBorder;
	/** Maximum of the side length for a single part of the Virtual Texture Atlas */
	UINT32 mMaxAtlasPartSize;
	/** Quality parameter for the Jpeg compression algorithm (the higher, the better), value in [0..100] */
	UINT32 mPictureQuality;
	/** Side length of a single tile, possible values are 64, 128, 256 and 512 */
	UINT32 mTileSize;

	/** Side length of the gaussian filter kernel that is used for scaling of the images */
	UINT32 mKernelSize;
	/** Root mean square deviation of the gaussian function used for scaling of the images */
	float mKernelSigma;

	/** Number of images in the horizontal direction in the optional imageBlock */
	UINT32 mImageBlockWidth;
	/** Number of images in the vertical direction in the optional imageBlock */
	UINT32 mImageBlockHeight;
	/** Names of all the images in the optional imageBlock. The names have to be ordered from left to right, top to bottom */
	std::vector<std::string> mImageBlockImageNames;

	/** Enum value corresponding to the file format, that is used to store the tiles in the Tile Store */
	VTTImageFormat mTilesFormat;
	/** Enum value corresponding to the file format, that is used to store the Atlas parts */
	VTTImageFormat mAtlasFormat;

	void Reset( void );
};

#endif